import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

/**
 * @Classname GetWebPageMusicInfo
 * @Description TODO
 * @Date 2024/6/12 16:02
 * @Created by PC
 */
public class GetWebPageMusicInfo {

    public static final String MAIN_PATH = "D:\\MySpace\\Space\\Music\\MusicTemp";
    public static final String CHROME_DRIVER_PATH = "C:\\CodeEnvironment\\chromedriver-win64\\chromedriver.exe";
    public static final String BACK_SLASH = "\\";
    public static final String DELETE_FILE_RECORD_PATH = "D:\\MySpace\\Space\\Music\\deleteFileRecord.txt";
    public static final String FILE_NAME_INFO_PNG = "info.png";
    public static final String FILE_NAME_INFO_TXT = "info.txt";

    public static void main(String[] args) throws Exception {
        File file = new File(MAIN_PATH);
        File[] files = file.listFiles();
        // 获取目标路径
        List<String> sourcePathStrings = Arrays.stream(files)
                .map(File::getPath)
                .collect(Collectors.toList());
        IntStream.range(0, sourcePathStrings.size())
                .forEach(index -> {
                    String sourcePathStringItem = sourcePathStrings.get(index);
                    String fileCode = sourcePathStringItem.replace(MAIN_PATH + BACK_SLASH, "");
                    try {
                        execute(sourcePathStringItem, fileCode);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
        System.out.println("===========All Final===========");
    }

    public static void execute(String sourcePathString, String fileCode) throws Exception {
        // 获取谷歌驱动
        ChromeDriver driver = getChromeDriver();
        // 通过文件code寻找目标url
        getTargetUrl(driver, fileCode);
        // 主要文件信息
        createTargetFileTextInfo(driver, sourcePathString);
        // 网页截图
        createTargetFilePicture(driver, sourcePathString);
        // 创建目标目录
        String targetFilePath = createTargetDirectory(driver, sourcePathString);
        // 移动
        moveDirectory(sourcePathString, targetFilePath);
        // 删除前目录
        deleteSourceDirectory(sourcePathString, fileCode);
    }

    private static void createTargetFilePicture(ChromeDriver driver, String sourcePathString) throws IOException {
        //设置浏览器弹窗页面的大小
        driver.manage().window().maximize();
        // 与浏览器同步非常重要，必须等待浏览器加载完毕
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        //使用getScreenshotAs进行截取屏幕
//        WebElement findElementByXPath = driver.findElement(By.xpath("//*[@id=\"main-content\"]"));
        WebElement findElementByXPath = driver.findElementByClassName("post-inner");
        JavascriptExecutor js = (JavascriptExecutor) driver;
        //移动到元素element对象的“顶端”与当前窗口的“顶部”对齐
        //js.executeScript("arguments[0].scrollIntoView();", element);
        js.executeScript("arguments[0].scrollIntoView(true);", findElementByXPath);
        //移动到元素element对象的“底端”与当前窗口的“底部”对齐
        //js.executeScript("arguments[0].scrollIntoView(false);", element);
        File screenshotAs = findElementByXPath.getScreenshotAs(OutputType.FILE);
        String pictureName = sourcePathString + BACK_SLASH + FILE_NAME_INFO_PNG;
        FileOutputStream fileOutputStream = new FileOutputStream(pictureName);
        FileInputStream fileInputStream = new FileInputStream(screenshotAs);
        try {
            byte[] arr = new byte[1024];
            int len;
            while ((len = fileInputStream.read(arr)) != -1) {
                fileOutputStream.write(arr, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fileInputStream.close();
            fileOutputStream.close();
        }
    }

    private static void createTargetFileTextInfo(ChromeDriver driver, String sourcePathString) throws IOException {
        String fileTextInfo = driver.findElement(By.id("main-content"))
                .findElement(By.className("entry"))
                .findElements(By.tagName("p"))
                .get(1).getText();
        FileWriter fileWriter = new FileWriter(sourcePathString + BACK_SLASH + FILE_NAME_INFO_TXT, true);
        fileWriter.write(fileTextInfo);
        fileWriter.close();
    }

    private static void getTargetUrl(ChromeDriver driver, String fileCode) {
        String targetBeforeUrl = "https://eroge-sharing.net/?s=" + fileCode;
        driver.get(targetBeforeUrl);
        // 找到超链接
        String url = driver.findElementByClassName("post-box-title")
                .findElement(By.tagName("a"))
                .getAttribute("href");
        driver.get(url);
    }

    private static ChromeDriver getChromeDriver() {
        //配置本地的chromediver.exe谷歌的内核
        System.setProperty("webdriver.chrome.driver", CHROME_DRIVER_PATH);
        //设置ChromeOptions打开方式，设置headless：不弹出浏览器
        ChromeOptions chromeOptions = new ChromeOptions();
        //方法一：通过setHeadless方法直接设置
//        chromeOptions.setHeadless(true);
        //设置好使用ChromeDriver使用
        ChromeDriver driver = new ChromeDriver(chromeOptions);
        return driver;
    }

    private static String createTargetDirectory(ChromeDriver driver, String sourcePathString) throws Exception {
        // 获取主要文件名字
        String mainName = driver.findElement(By.id("main-content"))
                .findElement(By.id("crumbs"))
                .findElement(By.className("current"))
                .getText();
        // 处理名字特殊符号导致失败的情况
        String dealMainName = mainName.replace("?", "");
        String targetFilePath = sourcePathString.substring(0, sourcePathString.lastIndexOf(BACK_SLASH)) + BACK_SLASH + dealMainName;
        if (!new File(targetFilePath).mkdir()) {
            System.out.println("目录创建失败");
            throw new Exception("目录创建失败");
        }
        return targetFilePath;
    }

    private static void moveDirectory(String sourcePathString, String targetFilePath) throws IOException {
        File toMoveFilesInfo = new File(sourcePathString);
        File[] toMoveFileItems = toMoveFilesInfo.listFiles();
        for (File toMoveFileItem : toMoveFileItems) {
            Path sourcePath = toMoveFileItem.toPath();
            String fileItemName = toMoveFileItem.getName();
            Path targetPath = Paths.get(targetFilePath, fileItemName);
            Files.move(sourcePath, targetPath, REPLACE_EXISTING);
        }
    }

    private static void deleteSourceDirectory(String sourcePathString, String fileCode) throws IOException {
        File sourceFile = new File(sourcePathString);
        int length = sourceFile.listFiles().length;
        if (Objects.equals(0, length)) {
            sourceFile.delete();
            System.out.println(fileCode);
            // 记录删除的文件code
            FileWriter deleteFileRecordFileWriter = new FileWriter(DELETE_FILE_RECORD_PATH, true);
            deleteFileRecordFileWriter.write(fileCode + "\n");
            deleteFileRecordFileWriter.close();
        }
    }

}
